#pragma once

#include "Singleton.h"
#include "const.h"
#include "data.h"

#include <functional>
#include <memory>
#include <thread>
#include <queue>
#include <map>
#include <condition_variable>
#include <unordered_map>
#include <json/value.h>

class CSession;
class LogicNode;
class UserInfo;

using FunCallback = std::function<void(std::shared_ptr<CSession>, const short& msg_id, const std::string& msg_data)>;

class LogicSystem : public Singleton<LogicSystem>
{
	friend class Singleton<LogicSystem>;

public:
	~LogicSystem();

	void postMsgToQue(std::shared_ptr<LogicNode> msg);

private:
	LogicSystem();

	// 判断是否全是数字
	bool isPureDigit(const std::string& str);
	void getUserByUid(std::string uid_str, Json::Value& rtvalue);
	void getUserByName(std::string name, Json::Value& rtvalue);
	// 从mysql获取好友申请列表
	bool getFriendApplyInfo(int to_uid, std::vector<std::shared_ptr<ApplyInfo>>& list);
	// 从mysql获取好友列表
	bool getFriendList(int self_id, std::vector<std::shared_ptr<UserInfo>>& user_list);

	// 从Redis中查询用户信息, 如果为查询到，则查询Mysql，并将数据写入Redis
	bool getBaseInfo(std::string base_key, int uid, std::shared_ptr<UserInfo>& userinfo);

	void dealMsg();
	void processMessage(std::shared_ptr<LogicNode> msg_node);
	// 注册对应消息id的回调函数
	void registerCallbacks();
	// 进行登录消息的回调
	void loginHandler(std::shared_ptr<CSession> session, const short& msg_id, const std::string& msg_data);
	// 搜索好友列表
	void searchInfo(std::shared_ptr<CSession> session, const short& msg_id, const std::string& msg_data);
	// 添加好友的回复处理
	void addFriendApply(std::shared_ptr<CSession> session, const short& msg_id, const std::string& msg_data);
	// 同意好友申请的校验
	void authFriendApply(std::shared_ptr<CSession> session, const short& msg_id, const std::string& msg_data);
	// 转发发送过来的消息
	void dealChatTextMsg(std::shared_ptr<CSession> session, const short& msg_id, const std::string& msg_data);

private:
	std::queue<std::shared_ptr<LogicNode>> m_msg_que;
	std::mutex m_mtex;
	std::condition_variable m_cond;
	std::atomic_bool m_b_stop;
	std::map<unsigned short, FunCallback> m_fun_callbacks_map; // id与其回调函数的映射
	std::unordered_map<int, std::shared_ptr<UserInfo>> m_users;
	std::thread m_worker_thread;
};

